﻿namespace MicroCloud.Api.Audit.Areas.Admin.Controllers.Audit
{
    /// <summary>
    /// 数据审计
    /// </summary>
    [Description("数据审计")]
    [ModuleInfo(Code = "AuditEntity", Name = "数据审计", OrderNo = 1, Position = "Audit", PositionName = "审计模块")]
    public class AuditEntityController : AdminControllerBase
    {
        #region "属性"
        #region "获取 审计模块业务契约"
        /// <summary>
        /// 获取 审计模块业务契约
        /// </summary>
        protected IAuditContract AuditContract => ServiceProvider.GetService<IAuditContract>();
        #endregion

        #endregion

        #region "Action方法"
        #region "读取数据审计信息列表"
        /// <summary>
        /// 读取数据审计信息列表
        /// </summary>
        /// <param name="request">页请求</param>
        /// <returns></returns>
        [HttpPost]
        [ModuleInfo]
        [Description("读取")]
        public virtual PageData<AuditEntityOutputDto> Read(PageRequest request)
        {
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            Expression<Func<AuditEntity, bool>> predicate = FilterService.GetExpression<AuditEntity>(request.FilterGroup);
            request.AddDefaultSortCondition(new SortCondition("Operation.CreatedTime", ListSortDirection.Descending));

            PageResult<AuditEntityOutputDto> page;
            using (var scope = ServiceProvider.CreateScope())
            {
                var userRepository = scope.ServiceProvider.GetService<IRepository<User, long>>();

                page = CacheService.ToPageCache(AuditContract.AuditEntities, predicate, request.PageCondition, m => new AuditEntityOutputDto
                {
                    Id = m.Id,
                    Name = m.Name,
                    TypeName = m.TypeName,
                    EntityKey = m.EntityKey,
                    OperateType = m.OperateType,
                    UserId = m.Operation.UserId,
                    UserName = GetUser(userRepository, m.Operation.UserId).UserName,
                    UserNickname = GetUser(userRepository, m.Operation.UserId).NickName,
                    FunctionName = m.Operation.FunctionName,
                    CreatedTime = m.Operation.CreatedTime,
                    Properties = AuditContract.AuditProperties.Where(n => n.AuditEntityId == m.Id).OrderBy(n => n.FieldName != "Id").ThenBy(n => n.FieldName).Select(n => new AuditPropertyOutputDto()
                    {
                        DisplayName = n.DisplayName,
                        FieldName = n.FieldName,
                        OriginalValue = n.OriginalValue,
                        NewValue = n.NewValue,
                        DataType = n.DataType
                    }).ToList()
                }, function);
            }

            return page.ToPageData();
        }
        #endregion

        #endregion

        #region "受保护的方法"
        #region "获取用户信息"
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userRepository">用户仓储模型</param>
        /// <param name="userId">用户编号</param>
        /// <returns></returns>
        [NonAction]
        [NonFunction]
        protected static UserSimpleDto GetUser(IRepository<User, long> userRepository, string userId)
        {
            if (userId.IsMissing())
            {
                return new UserSimpleDto();
            }
            var user = userRepository.QueryAsNoTracking(o => o.Id == userId.CastTo<long>()).ToCacheFirst<User, UserSimpleDto>(10, false, nameof(UserSimpleDto));
            return user ?? new UserSimpleDto();
        }
        #endregion

        #endregion

    }

}
